home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / trace / tcpdump-2.2.1 / print-tcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-25  |  6.7 KB  |  288 lines

  1. /*
  2.  * Copyright (c) 1988-1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-tcp.c,v 1.18 92/05/25 14:29:04 mccanne Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/param.h>
  28. #include <sys/types.h>
  29. #include <netinet/in.h>
  30. #include <netinet/in_systm.h>
  31. #include <netinet/ip.h>
  32. #include <netinet/ip_var.h>
  33. #include <netinet/tcp.h>
  34. #include <netinet/tcpip.h>
  35.  
  36. #ifdef X10
  37. #include <X/X.h>
  38. #include <X/Xproto.h>
  39. #endif
  40.  
  41. #include "interface.h"
  42. #include "addrtoname.h"
  43.  
  44. #ifndef TCPOPT_WSCALE
  45. #define    TCPOPT_WSCALE        3    /* window scale factor (rfc1072) */
  46. #endif
  47. #ifndef TCPOPT_SACKOK
  48. #define    TCPOPT_SACKOK        4    /* selective ack ok (rfc1072) */
  49. #endif
  50. #ifndef TCPOPT_SACK
  51. #define    TCPOPT_SACK        5    /* selective ack (rfc1072) */
  52. #endif
  53. #ifndef TCPOPT_ECHO
  54. #define    TCPOPT_ECHO        6    /* echo (rfc1072) */
  55. #endif
  56. #ifndef TCPOPT_ECHOREPLY
  57. #define    TCPOPT_ECHOREPLY    7    /* echo (rfc1072) */
  58. #endif
  59.  
  60. struct tha {
  61.     struct in_addr src;
  62.     struct in_addr dst;
  63.     u_int port;
  64. };
  65.  
  66. struct tcp_seq_hash {
  67.     struct tcp_seq_hash *nxt;
  68.     struct tha addr;
  69.     tcp_seq seq;
  70.     tcp_seq ack;
  71. };
  72.  
  73. #define TSEQ_HASHSIZE 919
  74.  
  75. static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
  76.  
  77.  
  78. void
  79. tcp_print(tp, length, ip)
  80.     register struct tcphdr *tp;
  81.     register int length;
  82.     register struct ip *ip;
  83. {
  84.     register u_char flags;
  85.     register int hlen;
  86.  
  87.     if ((u_char *)(tp + 1)  > snapend) {
  88.         printf("[|tcp]");
  89.         return;
  90.     }
  91.     if (length < sizeof(struct tcphdr)) {
  92.         (void)printf("truncated-tcp %d", length);
  93.         return;
  94.     }
  95.  
  96.     NTOHS(tp->th_sport);
  97.     NTOHS(tp->th_dport);
  98.     NTOHL(tp->th_seq);
  99.     NTOHL(tp->th_ack);
  100.     NTOHS(tp->th_win);
  101.     NTOHS(tp->th_urp);
  102.  
  103.     (void)printf("%s.%s > %s.%s: ",
  104.         ipaddr_string(&ip->ip_src), tcpport_string(tp->th_sport),
  105.         ipaddr_string(&ip->ip_dst), tcpport_string(tp->th_dport));
  106.  
  107.     if (!qflag) {
  108. #ifdef X10
  109.         register int be;
  110.  
  111.         if ((be = (tp->th_sport == X_TCP_BI_PORT ||
  112.             tp->th_dport == X_TCP_BI_PORT)) ||
  113.             tp->th_sport == X_TCP_LI_PORT ||
  114.             tp->th_dport == X_TCP_LI_PORT) {
  115.             register XReq *xp = (XReq *)(tp + 1);
  116.  
  117.             x10_print(xp, length - sizeof(struct tcphdr), be);
  118.             return;
  119.         }
  120. #endif
  121.     }
  122.  
  123.     if (qflag) {
  124.         (void)printf("tcp %d", length - tp->th_off * 4);
  125.         return;
  126.     }
  127.     if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH)) {
  128.         if (flags & TH_SYN)
  129.             putchar('S');
  130.         if (flags & TH_FIN)
  131.             putchar('F');
  132.         if (flags & TH_RST)
  133.             putchar('R');
  134.         if (flags & TH_PUSH)
  135.             putchar('P');
  136.     } else
  137.         putchar('.');
  138.  
  139.     if (!Sflag && (flags & TH_ACK)) {
  140.         register struct tcp_seq_hash *th;
  141.         register int rev;
  142.         struct tha tha;
  143.         /*
  144.          * Find (or record) the initial sequence numbers for
  145.          * this conversation.  (we pick an arbitrary
  146.          * collating order so there's only one entry for
  147.          * both directions).
  148.          */
  149.         if (tp->th_sport < tp->th_dport ||
  150.             (tp->th_sport == tp->th_dport &&
  151.              ip->ip_src.s_addr < ip->ip_dst.s_addr)) {
  152.             tha.src = ip->ip_src, tha.dst = ip->ip_dst;
  153.             tha.port = tp->th_sport << 16 | tp->th_dport;
  154.             rev = 0;
  155.         } else {
  156.             tha.src = ip->ip_dst, tha.dst = ip->ip_src;
  157.             tha.port = tp->th_dport << 16 | tp->th_sport;
  158.             rev = 1;
  159.         }
  160.  
  161.         for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
  162.              th->nxt; th = th->nxt)
  163.             if (!bcmp((char *)&tha, (char *)&th->addr,
  164.                   sizeof(th->addr)))
  165.                 break;
  166.  
  167.         if (!th->nxt || flags & TH_SYN) {
  168.             /* didn't find it or new conversation */
  169.             if (!th->nxt)
  170.                 th->nxt = (struct tcp_seq_hash *)
  171.                     calloc(1, sizeof (*th));
  172.             th->addr = tha;
  173.             if (rev)
  174.                 th->ack = tp->th_seq, th->seq = tp->th_ack - 1;
  175.             else
  176.                 th->seq = tp->th_seq, th->ack = tp->th_ack - 1;
  177.         } else {
  178.             if (rev)
  179.                 tp->th_seq -= th->ack, tp->th_ack -= th->seq;
  180.             else
  181.                 tp->th_seq -= th->seq, tp->th_ack -= th->ack;
  182.         }
  183.     }
  184.     hlen = tp->th_off * 4;
  185.     length -= hlen;
  186.     if (length > 0 || flags & (TH_SYN | TH_FIN | TH_RST))
  187.         (void)printf(" %lu:%lu(%d)", tp->th_seq, tp->th_seq + length, 
  188.                  length);
  189.     if (flags & TH_ACK)
  190.         (void)printf(" ack %lu", tp->th_ack);
  191.  
  192.     (void)printf(" win %d", tp->th_win);
  193.  
  194.     if (flags & TH_URG)
  195.         (void)printf(" urg %d", tp->th_urp);
  196.     /*
  197.      * Handle any options.
  198.      */
  199.     if ((hlen -= sizeof(struct tcphdr)) > 0) {
  200.         register u_char *cp = (u_char *)tp + sizeof(struct tcphdr);
  201.         int i;
  202.         char ch = '<';
  203.  
  204.         putchar(' ');
  205.         while (--hlen >= 0) {
  206.             putchar(ch);
  207.             switch (*cp++) {
  208.             case TCPOPT_MAXSEG:
  209.             {
  210.                 u_short mss;
  211. #ifdef TCPDUMP_ALIGN
  212.                 bcopy((char *)cp + 1, (char *)&mss, 
  213.                       sizeof(mss));
  214. #else
  215.                 mss = *(u_short *)(cp + 1);
  216. #endif                
  217.                 (void)printf("mss %d", ntohs(mss));
  218.                 if (*cp != 4)
  219.                     (void)printf("[len %d]", *cp);
  220.                 cp += 3;
  221.                 hlen -= 3;
  222.                 break;
  223.             }
  224.             case TCPOPT_EOL:
  225.                 (void)printf("eol");
  226.                 break;
  227.             case TCPOPT_NOP:
  228.                 (void)printf("nop");
  229.                 break;
  230.             case TCPOPT_WSCALE:
  231.                 (void)printf("wscale %d", cp[1]);
  232.                 if (*cp != 3)
  233.                     (void)printf("[len %d]", *cp);
  234.                 cp += 2;
  235.                 hlen -= 2;
  236.                 break;
  237.             case TCPOPT_SACKOK:
  238.                 (void)printf("sackOK");
  239.                 if (*cp != 2)
  240.                     (void)printf("[len %d]", *cp);
  241.                 cp += 1;
  242.                 hlen -= 1;
  243.                 break;
  244.             case TCPOPT_ECHO:
  245.             {
  246.                 u_long v;
  247. #ifdef TCPDUMP_ALIGN
  248.                 bcopy((char *)cp + 1, (char *)&v, 
  249.                       sizeof(v));
  250. #else
  251.                 v = *(u_long *)(cp + 1);
  252. #endif                
  253.                 (void)printf("echo %lu", v);
  254.                 if (*cp != 6)
  255.                     (void)printf("[len %d]", *cp);
  256.                 cp += 5;
  257.                 hlen -= 5;
  258.                 break;
  259.             }
  260.             case TCPOPT_ECHOREPLY:
  261.             {
  262.                 u_long v;
  263. #ifdef TCPDUMP_ALIGN
  264.                 bcopy((char *)cp + 1, (char *)&v, 
  265.                       sizeof(v));
  266. #else
  267.                 v = *(u_long *)(cp + 1);
  268. #endif                
  269.                 (void)printf("echoreply %lu", v);
  270.                 if (*cp != 6)
  271.                     (void)printf("[len %d]", *cp);
  272.                 cp += 5;
  273.                 hlen -= 5;
  274.                 break;
  275.             }
  276.             default:
  277.                 (void)printf("opt-%d:", cp[-1]);
  278.                 for (i = *cp++ - 2, hlen -= i + 1; i > 0; --i)
  279.                     (void)printf("%02x", *cp++);
  280.                 break;
  281.             }
  282.             ch = ',';
  283.         }
  284.         putchar('>');
  285.     }
  286. }
  287.  
  288.